#ifndef PH_HASHMAP_H
#define PH_HASHMAP_H

#include <unistd.h>
#include <string.h>

#include "hashf.h"

struct ph_hashmap_t;

typedef struct ph_hashmap_t ph_hashmap_t;

typedef ph_hashmap_t hm_t;

enum
{
	HM_NONE = 0,

	HM_K_COPY	= 0x01,
	HM_K_NOCOPY	= HM_NONE,

	HM_V_COPY	= 0x02,
	HM_V_NOCOPY	= HM_NONE,
};

enum
{
	HM_OK = 0,

	HM_NOMEM = -1,
	HM_BAD_ARG = -2,

	HM_ERR = 100,

	HM_NOT_FOUND	,

	HM_CAPA_LIMIT   ,
};

hm_t * hm_create0(int capa_k, int flags, hash_f hf);

static inline hm_t *
hm_create()
{
	return hm_create0(0, HM_K_COPY | HM_V_NOCOPY, simple_hash);
}

int hm_release(hm_t *hm);

int hm_put(hm_t *hm, void *k, size_t kl, void *d, size_t dl);
int hm_get(hm_t *hm, void *k, size_t kl, void **d, size_t *dl);
int hm_del(hm_t *hm, void *k, size_t kl, void **d, size_t *dl);

size_t hm_size(hm_t * hm);

int hm_foreach(hm_t * hm, int(*f)(void * ctx, void *k, size_t kl, void *d, size_t dl), void *ctx);

void hm_print(hm_t *hm);

static inline int
hm_put_str(hm_t *hm, const char *k, const char *v)
{
	return hm_put(hm, (void*)k, strlen(k), (void*)v, strlen(v));
}

static inline int
hm_get_str(hm_t *hm, const char *k, const char **v)
{
	return hm_get(hm, (void*)k, strlen(k), (void*)v, 0);
}

static inline int
hm_del_str(hm_t *hm, const char *k, const char **v)
{
	return hm_del(hm, (void*)k, strlen(k), (void*)v, 0);
}

#endif /* PH_HASHMAP_H */

